package prawnBot;

import lejos.nxt.LightSensor;
import lejos.nxt.UltrasonicSensor;
import lejos.nxt.LCD;
import lejos.util.Timer;
import lejos.util.TimerListener;
import javax.microedition.lcdui.Graphics;

/**
 * This class controls the information that is printed onto the LCD
 * screen of the Lego NXT brick. It runs on a timer, and refreshes constantly
 * with new information. Mainly, it prints the robot's x and y coordinates, and
 * orientation h, as well as the distance detected by the ultrasonic sensor(s)
 * abd the luminosity detected by the light sensor(s). It also prints a map of a
 * single 4' x 4' panel, and displays the robot's position and orientation on it.
 * 
 * @author Patrick Diez
 * @author Stephane Beniak - 260324952
 * 
 * @see Odometer
 * @see Navigation
 * @see USPoller
 * @see LineDetector
 * @see GridSnapper
 * @see Localizer
 */
public class LCDInfo implements TimerListener{
   
   /** Defines the default refresh period for the LCD screen, in ms. */
   public static final int LCD_REFRESH = 250;
   
   private Odometer odo;
   private USPoller usp;
   private LightSensor lsL;
   private LightSensor lsR;
   private Timer lcdTimer;
   
   private Graphics g;
   private int x, y, h;
   private double [] pos;
   
   /**
    * This constructor is to be passed all elements that are to have
    * their data printed to the screen.
    * 
    * @param odo_ The odometer tracking the robot's position.
    * @param usp_ The ultrasonic poller being used.
    * @param lsL_ The light sensor on the robot's left side.
    * @param lsR_ The light sensor on the robot's right side.
    */
   public LCDInfo(Odometer odo_, USPoller usp_, LightSensor lsL_, LightSensor lsR_) {
      odo = odo_;
      usp = usp_;
      lsL = lsL_;
      lsR = lsR_;
      g = new Graphics();
      lcdTimer = new Timer(LCD_REFRESH, this);
      
      pos = new double [3];
      lcdTimer.start();
   }
   
   /**
    * This method repeatedly prints the desired information (see class description)
    * to the LCD screen, on a Timer of set refresh rate.
    */
   public void timedOut() { 
      
      // Prints the robot's position values
      odo.getPosition(pos);
      LCD.clear();
      LCD.drawString("X:", 0, 0);
      LCD.drawString("Y:", 0, 1);
      LCD.drawString("H:", 0, 2);
      LCD.drawString("(" + odo.getNodeX() + "-" + odo.getNodeY() + "-" + odo.getDirection() + ")", 0, 3);
      LCD.drawString("DL:", 0, 4);
      LCD.drawString("DH:", 0, 5);
      LCD.drawString("LL:", 0, 6);
      LCD.drawString("LR:", 0, 7);
      LCD.drawInt((int)(pos[0] * 10), 2, 0);
      LCD.drawInt((int)(pos[1] * 10), 2, 1);
      LCD.drawInt((int)pos[2], 2, 2);
      LCD.drawInt((int)usp.usLo.getDistance(), 3, 4);
      LCD.drawInt((int)usp.usHi.getDistance(), 3, 5);
      LCD.drawInt((int)lsL.getNormalizedLightValue(), 3, 6);
      LCD.drawInt((int)lsR.getNormalizedLightValue(), 3, 7);
      
      // Print the grid on the screen
      g.drawRect(38, 2, 60, 60);
      g.drawLine(38, 17, 98, 17);
      g.drawLine(38, 32, 98, 32);
      g.drawLine(38, 47, 98, 47);
      g.drawLine(53, 2, 53, 62);
      g.drawLine(68, 2, 68, 62);
      g.drawLine(83, 2, 83, 62);
      
      // Print the robot's location on the grid
      x = (int)(38 + (pos[0]/2));
      y = (int)(62 - (pos[1]/2));
      
      g.drawRect(x - 2, y - 2, 4, 4);
      g.drawRect(x, y, 0, 0);
      
      // Print a dot representing the robot's orientation
      h = (int)((pos[2] + 22)/45);
      switch (h) {
         case 0:  g.drawRect(x - 1, y - 5, 2, 1); break;
         case 1:  g.drawRect(x + 4, y - 5, 1, 1); break;
         case 2:  g.drawRect(x + 4, y - 1, 1, 2); break;
         case 3:  g.drawRect(x + 4, y + 4, 1, 1); break;
         case 4:  g.drawRect(x - 1, y + 4, 2, 1); break;
         case 5:  g.drawRect(x - 5, y + 4, 1, 1); break;
         case 6:  g.drawRect(x - 5, y - 1, 1, 2); break;
         case 7:  g.drawRect(x - 5, y - 5, 1, 1); break;
         default: g.drawRect(x - 1, y - 5, 2, 1); break;
      }
      
   }
   
}